<template>
	<echelon-solutions>
		<!-- 这里是顶部导航栏 -->
		<skyline-navigation :title="utils.title"></skyline-navigation>
		<!-- 这里是中间区域 -->
		<central-hub>
			<view class="container  flex-column">
				<view
					style="position: sticky;top: var(--my-nav-h);z-index: calc(var(--date-z-index) - 1);background-color: #fff;padding: 10rpx;margin: -10rpx 0 20rpx;box-sizing: border-box;  box-shadow: 0 8rpx 10rpx -5rpx rgba(0,0,0,0.2);">
					<view class="flexGap flex-column">
						<MyDatePicker v-model="utils.date"></MyDatePicker>
						<view class="flexGap">
							<my-input v-model="utils.keyword" placeholder="帐号/地址/栋数/房号" class="w100"></my-input>
							<button v-if="utils.is_type===2" @click="tabStatus()"
								:type="!utils.isQuick?'primary':'warn'" class="w30">切换类型</button>
							<button type="primary" @click="handleSearch(true)" class="w30">搜索</button>
						</view>
						<view class="flexGap Aitems-center">
							<my-select :options="recentYearsMonthDaysStart" v-model="utils.date"
								@change="handleSearch('',$event)"></my-select>
							<button @click="convertToJsonString()" class="w30">全部复制</button>
						</view>
						<view class="flexGap">
							<my-input v-model="filterSearch" placeholder="过虑搜索-只过滤当前账单" class="w100"></my-input>
							<button class="w30" @click="generateImg" :disabled="!formData">生成图片</button>
							<button class="w30" @click="generateDom" :disabled="!formData">生成Dom</button>
						</view>
						<view class="flexGap">
							<button @click="handleFixed()" :type="getFixed.fixed?'primary':''"
								v-if="hasOperate">显示操作</button>
							<button :type="!multipleForm.selectable?'primary':'warn'"
								@click="muSe">{{multipleForm.selectable?'关闭多选':'开启多选'}}</button>
						</view>
						<view class="flexGap">
							<button type="primary" @click="handleOpen()"
								v-if="utils.is_type!==1&&hasc('details')">新增</button>
						</view>
					</view>
				</view>
				<view v-for="(v,i) of GetFilterData">
					<template v-if="!v.total">
						<view class="title" style="zoom: .5;">
							<view>{{v.title}}</view>
						</view>
						<!-- 使用自定义表格组件 -->
						<MyTreeTable :columns="columnsData" :data-source="v.displayedItems" style="zoom: .7;"
							:selectable="multipleForm.selectable" v-model="v.rowAll">
							<!-- 自定义操作列 -->
							<template #operate="{ data }">
								<view class="flexGap">
									<button @click="submitFormPay(data,true)" v-if="has('/bill/details/pay')&&quickFlag"
										type="primary" :disabled="!getFees(data)||data.is_active===1">缴费</button>
									<button @click="handleOpen(data)" v-if="hasu('details')">编辑</button>
									<button type="warn" v-if="hasr('details')" @click="handleDelete(data)">删除</button>
									<button @click="convertToJsonString({...data,name:v.name})">复制</button>
									<button v-if="has('/bill/details/pay')&&quickFlag"
										:type="data.is_active===1?'primary':'warn'"
										@click="handleIs_active(data)">{{data.is_active===1?'已停用':'停用'}}</button>
								</view>
							</template>
						</MyTreeTable>
					</template>
				</view>
				<view class="title zoom3" style="background-color: red;color: white;">表格和图片分割界</view>
				<view class="flexGap flex-column">
					<image class="gap_img w100" :src="v" v-for="(v,i) of images" mode="widthFix"
						@click="previewImage(i)">
					</image>
				</view>
				<MyPopup v-model="popup.visible">
					<MyForm :fields="formFields" @submit="submitForm" :submit-text="popup.submit_txt" :filters="['id']"
						@handleexpirationDate="popupHandleexpirationDate" :updateNames="['remarks']">
					</MyForm>
				</MyPopup>
				<MyPopup v-model="Pay.visible">
					<MyForm :fields="Pay.formFields" @submit="submitFormPay" submit-text="缴费"
						:filters="['ik','ik_name','account_id']" @handleexpirationDate="handleexpirationDate"
						:updateNames="['monthlyPackage','remarks']">
						<view>如需要升级套餐请联系网络管理员</view>
					</MyForm>
				</MyPopup>
				<MyPopup v-model="convert.visible">
					<view class="flexGap flex-column">
						<textarea class="convert-textarea" v-if="convert.form" v-model="convert.value"></textarea>
						<textarea class="convert-textarea" v-else v-model="convert.allvalue"></textarea>
						<button type="primary" @click="convertString()">确定复制</button>
					</view>
				</MyPopup>
				<view class="my-mask" v-if="isMask">
					<view class="my-mask-overlay"></view>
					<view class="my-mask-content">
						<div class="loading-icon"></div>
						<view class="loading-text">加载中...</view>
					</view>
				</view>

			</view>
		</central-hub>
	</echelon-solutions>
</template>

<script>
	export default {
		methods: {
			handleIs_active(formData) {
				uni.showModal({
					title: formData?.is_active === 1 ? '启用' : '停用',
					confirmText: '是否' + (formData?.is_active === 1 ? '启用' : '停用'),
					success: async (res) => {
						if (res.confirm) {
							await this.requestApi((formData?.is_active === 1 ? 'enable' :
									'stop'), [{
									...formData,
									is_active: (formData.is_active === 1 ? 0 : 1)
								}],
								1);
						}
					}
				});
			},
			muSe() {
				this.multipleForm.selectable = !this.multipleForm.selectable;
				if (!this.multipleForm.selectable) {
					this.dataList.forEach(it => {
						it.rowAll = [];
					})
				}
			},
			popupHandleexpirationDate(e) {
				const expirationDate = this.formFields.find(it => it.name === 'expirationDate');
				const remarks = this.formFields.find(it => it.name === 'remarks');
				const formItem = expirationDate.options.find(it => it.value === e);
				remarks.value = '新装' + (formItem ? formItem.label : '');
			},
			handleexpirationDate(e) { // 选中多少个月
				const expirationDate = this.Pay.formFields.find(it => it.name === 'expirationDate');
				const monthlyPackage = this.Pay.formFields.find(it => it.name === 'monthlyPackage');
				const remarks = this.Pay.formFields.find(it => it.name === 'remarks');
				const formItem = expirationDate.options.find(it => it.value === e);
				if (formItem) {
					monthlyPackage.value = (monthlyPackage.origPrice * formItem.index).toFixed(2);
				}
				remarks.value = '续费' + (formItem ? formItem.label : '');
			},
			// 初始化数据
			async initData(data = encodeURIComponent(JSON.stringify(this.$storage.get('login'))), title, is_type) {
				const info = JSON.parse(data);
				this.utils.info = info; // 个人信息
				this.account_id = info.account_id; // 账号id
				this.recentYearsMonthDaysStart = this.getRecentYearsMonthDays(2); // 当前时间和前年时间列表 
				// 生成表单列表
				const generateFormField = (label, type, name, value = "", required = true, disabled = false, date =
					false,
					options) => {
					return {
						label,
						type,
						name,
						value,
						required,
						disabled,
						date,
						options
					};
				};
				const {
					parent_id,
					role_id
				} = this.$storage.get('login');
				const flag = !!parent_id ? role_id !== 9 : !!parent_id;
				const fields = [
					generateFormField("为其新增", "text", "account_id", info.account_id, true,
						false,
						false, []),
					generateFormField("上网帐号", "text", "username", "", true, false),
					generateFormField("安装日期", "text", "createDate", "", true, flag, true),
					generateFormField("栋号", "text", "buildingNo", "", true),
					generateFormField("地址", "text", "address", "", true),
					generateFormField("联系电话", "text", "phone", "", false),
					generateFormField("按天收费", "text", "dailyFee", ""),
					generateFormField("安装费", "text", "activationFee", ""),
					generateFormField("套餐月租", "text", "monthlyPackage", "", true, false),
					generateFormField("兆数", "text", "bandwidth", ""),
					generateFormField("套餐", "text", "expirationDate", "", false, false, false, []),
					generateFormField("到期日期", "text", "expirationDate", "", true, false, true),
					generateFormField("类型", "text", "remarks", ""),
					{
						...generateFormField("续费默认", "text", "renewal", "", false),
						placeholder: '缴费使用此值要填大于0的值才会被继承'
					},
					generateFormField("服务器", "text", "servers", 1, true, false, false, [{
						label: '后台服务器',
						value: 1,

					}, {
						label: '前台服务器',
						value: 0,
					}]),
				];
				this.formFields = [...this.generateFormFields(fields)]; // 表单列表

				// 缴费
				const PayFields = [
					generateFormField("服务器下标", "text", "ik", "", true, true),
					generateFormField("服务器名称", "text", "ik_name", "", true, true),
					generateFormField("账号id", "text", "account_id", "", true, true),
					generateFormField("上网帐号", "text", "username", "", true, true),
					generateFormField("安装日期", "text", "createDate", "", true, flag, true),
					generateFormField("栋号", "text", "buildingNo", "", true, true),
					generateFormField("地址", "text", "address", "", true, true),
					generateFormField("联系电话", "text", "phone", "", false),
					generateFormField("安装费",
						"text", "activationFee", "0", true, flag),
					generateFormField("按天收费", "text", "dailyFee", "0", true, flag),
					generateFormField("套餐月租", "text", "monthlyPackage", "", true, flag),
					generateFormField("兆数", "text", "bandwidth", "", true, flag),
					generateFormField("套餐", "text", "expirationDate", "", false, false, false, []),
					generateFormField("到期日期", "text", "expirationDate", "", true, flag, true),
					generateFormField("类型", "text", "remarks", "", true, flag),
					generateFormField("服务器", "text", "servers", 1, true, flag, false, [{
						label: '后台服务器',
						value: 1,

					}, {
						label: '前台服务器',
						value: 0,
					}]),
				];
				this.Pay.formFields = [...this.generateFormFields(PayFields)]; // 表单列表
				this.utils.title = title; //默认导航栏
				this.utils.is_type = Number(is_type); // 身份  
				if (Number(is_type) === 0) {
					this.utils.keyword = ''
				}
				if (this.utils.is_type !== 2) {
					this.utils.date = this.getDateToday(); // 默认当前时间
				} else {
					this.utils.date = this.recentYearsMonthDaysStart.find(v => v.label === '全部')?.value; // 默认当前时间
				}
				const columns = [
					'ID,id,left',
					'上网账号,username',
					'到期日期,expirationDate', '栋号,buildingNo',
					'地址,address', '联系电话,phone', '兆数,bandwidth', '安装费,activationFee', '按天收费,dailyFee',
					'套餐月租,monthlyPackage', '备注,remarks', '合计,amountReceived',
					'预结金额,projectedAmount', '剩余金额,netIncome'
				];
				this.columnsData = this.myColumns(columns); // 生成表头

			},
			// 提交合并 操作
			handleSubmit(formData, status, mess, vis) {

				const {
					username,
					ik_name,
					ik,
					address,
					bandwidth
				} = formData;
				if (vis) {
					if (!/[Mm]/.test(bandwidth)) {
						formData.bandwidth += "M";
					}
				}
				if (!ik_name || !ik) {
					uni.showToast({
						title: '暂无权限',
						duration: 2000
					});
					return false;
				}
				uni.showModal({
					title: '是否' + mess,
					success: async (res) => {
						if (res.confirm) {
							let payCorres = await this.$postPublic(['detail', 'payCorres'], formData);
							try {
								this.isMask = true;
								const data = await this.$postPublic(['detail', status], {
									...formData,
									url: payCorres.data.api,
									username,
									name: this.utils.info.name
								});
								uni.showToast({
									title: data.message,
									icon: 'none',
									duration: 2000
								});
								if (vis) {
									vis.visible = false;
								}
								this.isMask = false;
								this.handleSearch();
								this.handleErr([data]);
							} catch (err) {
								uni.showModal({
									title: err.message + '...' + '失败,是否重试',
									success: (res) => {
										if (res.confirm) {
											this.handleSubmit(formData, status, mess, vis);
										} else {
											if (vis) {
												vis.visible = false;
											}
										}
									}

								});
							}
						}
					}
				})
			},
			getCurrentDateFormatted() {
				const now = new Date();
				const year = now.getFullYear();
				// getMonth() 返回的月份是从0开始的，所以需要+1
				const month = now.getMonth() + 1;
				const day = now.getDate();

				// 使用模板字符串和三元运算符确保月份和日期始终是两位数字
				return `${year}/${month < 10 ? '0' + month : month}/${day < 10 ? '0' + day : day}`;
			},

			/**
			 * 表单操作
			 */
			// 打开弹框
			handleOpen(data, flag) {
				if (!data) {
					this.formFields = this.formFields.filter(v => v.name !== 'id');
					this.formFields[0].value = this.account_id; // 设置当前账号id，把它删除新增时会自动为上次的账号编辑的账号id设置进去
					this.formFields[0].disabled = false;
					this.formFields.forEach(v => {
						if (v.name === 'createDate') {
							v.value = this.getDateToday(true);
						} else if (v.name === 'expirationDate') {
							v.options = this.generateDateOptions(this.getCurrentDateFormatted());
							v.value = v.options[0].value;
						} else if (v.name === 'remarks') {
							v.value = '新装包月'
						}
					})
					this.popup.submit_txt = '添加';
					this.popup.visible = !this.popup.visible;
				} else if (flag) { // 缴费    

					this.Pay.formFields.forEach(v => {
						if (v.name === 'createDate') {
							v.value = data.expirationDate
						} else if (v.name === 'expirationDate') {
							v.options = this.generateDateOptions(data.expirationDate);
							v.value = v.options[0].value;
						} else if (v.name === 'remarks') {
							v.value = '续费包月'
						} else if (v.name === 'servers') {

						} else if (v.name === 'dailyFee') {

						} else if (v.name === 'monthlyPackage') {
							v.value = data.renewal || data.monthlyPackage;
							v.origPrice = v.value;
						} else if (v.name === 'activationFee') {

						} else {
							v.value = data[v.name];
						}
					});
					this.Pay.visible = !this.Pay.visible;
				} else {
					this.formFields.forEach(v => {
						v.value = data[v.name];
						return v;
					});
					this.formFields[0].disabled = true;
					this.formFields.unshift({
						label: "修改id",
						type: "text",
						name: "id",
						value: data.id,
						required: true,
						disabled: true,
					});
					this.popup.submit_txt = '修改';
					this.popup.visible = !this.popup.visible;
				}
			},
			submitForm(formData) {
				const findAccount = this.allAccountInfo.find(it => it.id === formData.account_id);
				const {
					ik,
					ik_name
				} = findAccount || this.utils.info;
				if (formData.id) {
					this.handleSubmit({
						...formData,
						ik,
						ik_name
					}, 'update', '修改', this.popup);
				} else {
					this.handleSubmit({
						...formData,
						ik,
						ik_name
					}, 'create', '新增', this.popup);
				}
			},
			// 是否过期需要缴费
			getFees(data) {
				if (!this.quickFlag) return false;

				const expirationDateString = data.expirationDate;
				const expirationDate = new Date(expirationDateString);
				const currentDate = new Date();
				const lastDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 2, 0);

				if (expirationDate <= lastDayOfMonth && expirationDate >= currentDate || expirationDate <=
					lastDayOfMonth) {
					return 'warn';
				} else {
					return '';
				}
			},
			async GetCorrespondingSubwebs(formData) {
				const {
					data
				} = await this.$postPublic(['detail', 'payCorres'], formData);
				data.ik = formData.ik;
				return data;
			},
			BatchProcessing(formData, status, url, back) {
				return new Promise(async (resolve, reject) => {
					const data = await this.$postPublic(['detail', status], {
						...formData,
						url,
						name: this.utils.info.name,
						...back ? back(formData) : {}
					});
					console.log(data);
					resolve(data);
				}).catch(err => {
					reject(err);
				});
			},

			handleErr(messages) {
				// 初始化一个空字符串用于存储包含"失败"关键词的提示信息
				let combinedMessage = "";

				// 遍历对象数组，找到包含"失败"关键词的对象并合并信息
				messages.forEach(obj => {
					if (obj.message.includes("失败")) {
						combinedMessage += obj.message + ' ';
					}
				});

				// 弹出合并的提示信息
				if (combinedMessage) {
					uni.showModal({
						title: '操作失败-提示',
						content: combinedMessage,
						icon: 'none'
					});
				}
			},
			getApiByIk(arr) {
				const map = new Map();
				arr.forEach(obj => {
					const ik = obj.ik;
					const api = obj.api;
					if (ik && api) {
						map.set(ik, api);
					}
				});

				return map;
			},
			uniqueRows(arr) {
				const uniqueKeys = new Set();
				return arr.filter(row => {
					const key = row.ik; // 使用 ik 或 ik_name 作为唯一标识
					if (!uniqueKeys.has(key)) {
						uniqueKeys.add(key);
						return true;
					}
					return false;
				});
			},
			// 缴费提交
			submitFormPay(formData, flag_open) {
				let rowAll = this.GetFilterData.flatMap(it => it.rowAll.filter(ro => this.getFees(ro))).filter(it => it
					.is_active !== 1);
				if (!(this.multipleForm.selectable && rowAll.length)) {
					rowAll = [formData];
					/* if (!this.getFees(formData)) {
						uni.showToast({
							title: '暂不能续费'
						});
						return false;
					} */
				}
				if (this.multipleForm.selectable && rowAll.length) {
					const {
						parent_id,
						role_id
					} = this.$storage.get('login');
					const flag = !!parent_id ? role_id !== 9 : !!parent_id;
					if (!flag) {
						uni.showModal({
							title: '多选缴费',
							confirmText: '前台缴费',
							cancelText: '后台缴费',
							success: (res) => {
								uni.showModal({
									title: '是否缴费',
									success: async (_) => {
										if (_.confirm) {
											const servers = res.confirm ? 0 : 1;
											await this.requestApi('pay', rowAll, servers, (it) =>
												({
													createDate: it.expirationDate,
													expirationDate: this
														.generateDateOptions(it
															.expirationDate)[0].value
												}));
										}
									}
								});
							}
						});
					} else {
						uni.showModal({
							title: '多选缴费',
							confirmText: '缴费',
							cancelText: '取消',
							success: async (res) => {
								if (res.confirm) {
									await this.requestApi('pay', rowAll, 1, (it) =>
										({
											createDate: it.expirationDate,
											expirationDate: this
												.generateDateOptions(it
													.expirationDate)[0].value
										}));

								}
							}
						});
					}

				} else if (flag_open) {
					this.handleOpen(formData, !!flag_open);
				} else {
					this.handleSubmit(formData, 'pay', '缴费', this.Pay);
				}

			},
			async requestApi(type, rowAll, servers, back) {
				this.isMask = true;
				const uniqueRows = this.uniqueRows(rowAll);
				const promises = uniqueRows.map(async it =>
					await this.GetCorrespondingSubwebs({
						...it,
						servers
					}));
				const GetCorres = await Promise.all(promises);
				const apiMap = this.getApiByIk(GetCorres);
				const promisesRowAll = rowAll.map(async it =>
					await this.BatchProcessing({
						...it,
						servers
					}, type, apiMap.get(it.ik), back));
				const data = await Promise.all(promisesRowAll);
				console.log(data);
				this.isMask = false;
				uni.showToast({
					title: '加载新数据',
					icon: 'none',
					duration: 2000
				});
				this.handleSearch();
				this.handleErr(data);
			},

			// 表格删除对应的数据
			handleDelete(formData) {
				let rowAll = this.GetFilterData.flatMap(it => it.rowAll);
				if (!(this.multipleForm.selectable && rowAll.length)) {
					rowAll = [formData];
				}
				uni.showModal({
					title: '多选删除',
					confirmText: '前台删除',
					cancelText: '后台删除',
					success: (res) => {
						uni.showModal({
							title: '是否删除',
							success: async (_) => {
								if (_.confirm) {
									const servers = res.confirm ? 0 : 1;
									await this.requestApi('remove', rowAll, servers);
								}
							}
						});
					}
				});
			},
			generateDateOptions(expirationDateStr) {
				const expirationDateArr = expirationDateStr.split('/');
				const year = parseInt(expirationDateArr[0]);
				const month = parseInt(expirationDateArr[1]);
				const day = parseInt(expirationDateArr[2]);

				function isValidDate(year, month, day) {
					const date = new Date(year, month - 1, day);
					if (date.getMonth() + 1 !== month) {
						const lastDay = new Date(year, month, 0).getDate();
						return new Date(year, month - 1, lastDay);
					}
					return date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day;
				}

				const result = isValidDate(year, month, day);
				const expirationDate = result instanceof Date ?
					`${result.getFullYear()}/${result.getMonth() + 1}/${result.getDate()}` : new Date(year, month - 1,
						day);
				// 将 data.expirationDate 转换为 Date 对象
				// 获取指定月份的最大日期
				const getMaxDaysInMonth = (date) => {
					const newDate = new Date(date.getFullYear(), date.getMonth() + 1, 0);
					return newDate.getDate();
				};

				// 计算指定时间段后的日期
				const addMonths = (date, months) => {
					const newDate = new Date(date);
					const currentDay = newDate.getDate();
					newDate.setDate(1);
					newDate.setMonth(newDate.getMonth() + months);
					const maxDaysInMonth = getMaxDaysInMonth(newDate);
					if (currentDay > maxDaysInMonth) {
						newDate.setDate(maxDaysInMonth);
					} else {
						newDate.setDate(currentDay);
					}

					return newDate;
				};

				// 封装生成 options 数组的函数
				const generateOptions = (expirationDate) => {
					const options = [];

					const timePeriods = [{
							label: '包月',
							value: 1
						},
						{
							label: '二个月',
							value: 2
						},
						{
							label: '三个月',
							value: 3
						},
						{
							label: '半年',
							value: 6
						},
						{
							label: '一年',
							value: 12
						}
					];

					timePeriods.forEach((period) => {
						const futureDate = addMonths(expirationDate, period.value);
						const formattedFutureDate =
							`${futureDate.getFullYear()}/${String(futureDate.getMonth() + 1).padStart(2, '0')}/${String(futureDate.getDate()).padStart(2, '0')}`;
						options.push({
							label: period.label,
							value: formattedFutureDate,
							index: period.value
						});
					});

					return options;
				};

				// 生成 options 数组
				return generateOptions(expirationDate);
			},
			/**
			 * 处理搜索操作
			 * @param {boolean} flag - 是否进行搜索操作的标志
			 * @param {string} [val=''] - 日期范围，默认为空字符串
			 */
			handleSearch(flag, val = '') {
				const {
					date,
					is_type,
					info,
					keyword,
					isQuick
				} = this.utils;
				let key;
				if (is_type === 2) {
					key = isQuick ? 'expirationDate' : 'createDate';
				} else {
					key = is_type ? 'expirationDate' : 'createDate';
				}
				// 根据传入参数或默认日期设置变量d
				const d = (val || date) || '';

				// 构建请求数据对象
				const data = {
					...info,
					[key]: d,
					keyword
				}

				// 将日期范围拆分为数组a和b
				const [a, b] = d.split('至');

				// 检查关键字是否为空，时间范围是否合法
				if (!keyword) {
					if (!a || !b) {
						if (!flag) return false;
						// 提示用户选择时间或输入内容
						uni.showToast({
							title: '请规范选好时间或输入内容'
						});
						return false;
					}
				}
				this.images = [];
				// 调用接口请求数据并处理返回结果
				this.$listPublic('detail', data, (list) => {
					this.allAccountInfo = list.allAccountInfo;
					this.formFields.forEach(it => {
						if (it.name === 'account_id') {
							it.options = list.allAccountInfo.map(v => ({
								label: v.name,
								value: v.id
							}))
						}
					});
					this.formData = data;
					// 更新数据列表
					this.dataList = list.data;
				});
			},
			generateImg() {
				this.isMask = true;
				const form = {
					...this.formData
				}; // 创建 this.formData 的浅拷贝赋值给 form
				this.formData = null; // 将 this.formData 设置为 null
				// 获取包含url属性的数据项并提取url，赋值给images
				this.images = [];
				this.$nextTick(async () => {
					const {
						data: imgArr
					} = await this.$postPublic(['detail', 'listImg'], form);
					this.images = imgArr;
					this.isMask = false;
				})
			},
			generateDom() {
				this.isMask = true;
				this.$nextTick(async () => {
					const {
						data
					} = await this.$postPublic(['detail', 'listDom'], this.formData);
					// #ifdef APP-PLUS
					plus.runtime.openURL(encodeURI(data.url))
					return
					// #endif
					window.open(data.url);
					this.isMask = false;
				})
			},
			// 是否展示操作固定
			handleFixed() {
				const columns = this.columnsData[this.columnsData.length - 1];
				this.$set(columns, 'fixed', columns.fixed ? '' : 'right');
			},
			// 切换类型（默认入网时间）
			tabStatus() {
				this.utils.isQuick = !this.utils.isQuick;
				this.handleSearch()
			},
			// 复制表格内容
			convertToJsonString(jsonData) {
				this.convert.visible = true;
				this.convert.form = jsonData;
			},
			convertString() {
				const jsonData = this.convert.form;
				const columns = [
					'ID,id',
					'上网账号,username',
					'到期日期,expirationDate', '栋号,buildingNo',
					'地址,address', '联系电话,phone', '兆数,bandwidth', '安装费,activationFee',
					'按天收费,dailyFee',
					'套餐月租,monthlyPackage', '备注,remarks', '合计,amountReceived',
					'预结金额,projectedAmount', '剩余金额,netIncome', '管理员,name'
				];
				let content = jsonData ? this.convert.value : this.convert.allvalue;
				const ksty = jsonData ? 'new-convert' : 'new-convert-all';
				this.$storage.set(ksty, content);
				const getString = (lines, jsonData) => {
					let resultString = '';
					lines.forEach(line => {
						const fields = line.split('+');
						let lineResult = '';
						fields.forEach(field => {
							const [fie, flag] = columns.flatMap(it => {
								const [a, b] = it.split(',');
								const af = field.trim().split(':');
								const [f, fs] = af;
								if (f === a || f === b) {
									if (af.length > 1) {
										return [b, fs];
									}
									return [b];
								}
							}).filter(it => it);
							const str = fie ? jsonData[fie] : field;
							lineResult += (flag ? flag + ':' + str : str) + ' ';
						});
						resultString += lineResult.trim() + '\n';
					});
					return resultString;
				}
				let resultString = '';
				const lines = content.split('\n');
				if (jsonData) {
					resultString = getString(lines, jsonData);
				} else {
					this.dataList.forEach((entry, index) => {
						// 添加 title 到结果字符串
						resultString +=
							`${entry.title} 共${entry.displayedItems.length}条\n\n`;
						if (entry.displayedItems && entry.displayedItems.length > 0) {
							entry.displayedItems.forEach((item, chIndex) => {
								const fee = item.monthlyPackage !== "0.00" ? item
									.monthlyPackage : item
									.amountReceived;
								resultString +=
									`${index}-${chIndex+1} ${getString(lines,{...item,name:entry.name})} \n\n`;
							});
						} else {
							resultString += `${index}-${0} 空的 \n`;
						}
						// 每个条目之后添加一个换行符以分隔不同的条目
						resultString += "\n";
					});
				}
				uni.setClipboardData({
					data: resultString,
					success: () => {
						this.convert.visible = false;
						this.convert.form = null;
					}
				});
			},

			// 生成对应的年月份
			getMonthDays(year) {
				const currentDate = new Date();
				const currentYear = currentDate.getFullYear(); // 获取当前年份
				const currentMonth = currentDate.getMonth() + 1; // 获取当前月份，getMonth() 返回的月份是从0开始计数的

				let monthDays = [];
				for (let month = 1; month <= 12; month++) {
					let daysInMonth = new Date(year, month, 0).getDate(); // 获取该月的天数
					let m = month > 9 ? month : '0' + month; // 格式化月份
					let value = `${year}-${m}至${year}-${m}`;
					let label = `${year}年${m}月`;

					// 只有当年月小于等于当前年月时，才添加到数组中  
					if (year < currentYear || (year === currentYear && month <= currentMonth)) {
						monthDays.push({
							value,
							label
						});
					}
				}

				return monthDays;


			},
			// 批量生成当前时间和前年时间事件
			getRecentYearsMonthDays(numYears) {
				let currentYear = new Date().getFullYear();
				let recentYearsMonthDays = [];
				const obj = {
					label: '全部'
				};
				for (let i = 0; i < numYears; i++) {
					let year = currentYear - i;
					let yearMonthDays = this.getMonthDays(year);
					if (i === 0) {
						const [{
							value
						}] = yearMonthDays.splice(-1);
						const [va] = value.split('至')
						obj.value = va
					} else if (i === 1) {
						const [{
							value
						}] = yearMonthDays;
						const [va] = value.split('至')
						obj.value = va + '至' + obj.value;
					}

					recentYearsMonthDays.push(...this.getMonthDays(year));
				}
				return ([{
					value: '',
					label: '请选择年月'
				}, obj, ...recentYearsMonthDays]);
			},

			// 获取本月时间
			getDateToday(falg, num = 0) {
				// 获取当前日期
				const today = new Date();
				if (falg) {
					const systemInfo = uni.getSystemInfoSync();
					// 根据平台类型返回不同的日期格式
					if (systemInfo.platform === 'android') {
						const today = new Date();
						const nextDate = new Date(today.getFullYear(), today.getMonth() + num, today.getDate());
						const year = nextDate.getFullYear();
						const month = String(nextDate.getMonth() + 1).padStart(2, '0');
						const day = String(nextDate.getDate()).padStart(2, '0');
						const formattedDate = `${year}-${month}-${day}`;
						return formattedDate;
					} else {
						return new Date(today.getFullYear(), today.getMonth() + num, today.getDate())
							.toLocaleDateString();
					}

				}


				// 获取当前月份的第一天
				const firstDayOfMonth = new Date(today.getFullYear(), today.getMonth(), 1);

				// 获取下一个月份的第一天
				const firstDayOfNextMonth = new Date(today.getFullYear(), today.getMonth() + 1, 1);

				// 获取当前月份的最后一天
				const lastDayOfMonth = new Date(firstDayOfNextMonth.getTime() - 1);

				// 格式化日期
				const formatDate = (date) => {
					const year = date.getFullYear();
					const month = String(date.getMonth() + 1).padStart(2, '0');
					return `${year}-${month}`;
				};
				// 将起始日期和结束日期格式化为字符串
				const startDate = formatDate(firstDayOfMonth);
				const endDate = formatDate(lastDayOfMonth);
				return startDate + '至' + endDate;
			},

			generateFormFields(fields) {
				return fields.filter(field => field);
			},
			// 获取前三个月的数据
			getPreviousThreeMonthsDateRangeString() {
				const date = new Date();
				// 获取当前日期的年、月和日
				const year = date.getFullYear();
				const month = date.getMonth() + 1; // 月份从0开始，需要加1

				// 计算前三个月的年和月
				let prevMonth = month - 3;
				let prevYear = year;
				if (prevMonth < 1) {
					prevMonth += 12;
					prevYear--;
				}

				// 构造起始日期和结束日期
				const startDate = new Date(prevYear, prevMonth - 1, 1); // 月份从0开始，需要减1
				const endDate = new Date(year, month - 1, 0); // 月份从0开始，需要减1

				// 提取起始日期和结束日期的年、月和日，并补零
				const startYear = startDate.getFullYear();
				const startMonth = String(startDate.getMonth() + 1).padStart(2, '0'); // 月份补零
				const startDay = String(startDate.getDate()).padStart(2, '0'); // 天数补零

				const endYear = endDate.getFullYear();
				const endMonth = String(endDate.getMonth() + 1).padStart(2, '0'); // 月份补零
				const endDay = String(endDate.getDate()).padStart(2, '0'); // 天数补零

				// 拼接起始日期和结束日期
				const startDateString = `${startYear}-${startMonth}-${startDay}`;
				const endDateString = `${endYear}-${endMonth}-${endDay}`;
				this.handleSearch('', `${startDateString}至${endDateString}`)
			},
			// 预览图片
			previewImage(index) {
				const itemList = ['转发到微信', '保存图片'];
				const ary = this.images;
				uni.previewImage({
					urls: ary, // 使用新的参数名 imageUrls
					current: index,
					longPressActions: {
						itemList,
						success: (data) => {
							const callBack = [
								() => {
									uni.share({
										provider: "weixin",
										scene: "WXSceneSession",
										type: 2,
										imageUrl: ary[index], // 使用 imageUrls 数组中的第一个图片路径
										success: function(res) {}
									});
								},
								() => {
									this.down(ary[index]);
								}
							];
							callBack[data.tapIndex]();
						},
						fail: function(err) {}
					}
				});
			},
			//下载海报，只在APP内有效
			down(url) {
				uni.downloadFile({ //下载
					url, //图片下载地址
					success: res => {
						if (res.statusCode === 200) {
							uni.saveImageToPhotosAlbum({ //保存图片到系统相册。
								filePath: res.tempFilePath, //图片文件路径
								success: function() {
									uni.showToast({
										title: '图片保存成功',
										icon: 'none',
									});
								},
								fail: function(e) {
									console.log(e);
									uni.showToast({
										title: '图片保存失败',
										icon: 'none',
									});
								}
							});
						}
					}
				});
			},

			// 生成表格头
			myColumns(columnData) {
				return columnData.map(data => {
					const [title, key, fixed] = data.split(',');
					const column = {
						title,
						key
					};
					if (fixed) {
						column.fixed = fixed;
					}
					return column;
				});
			}

		},
		onLoad({
			data,
			title,
			is_type
		}) {
			this.initData(data, title, is_type);
		},
		data() {
			return {
				formData: null,
				isMask: false,
				convert: {
					visible: false,
					value: this.$storage.get('new-convert') ||
						`上网账号\n备注+兆数+按天收费+套餐月租:月租\n安装费:安装费\n合计:合计\n到期日期:到期日期\n地址+栋号\n管理员:管理员\n已安装`,
					form: null,
					allvalue: this.$storage.get('new-convert-all') ||
						`上网账号\n备注+兆数+按天收费+套餐月租:月租\n安装费:安装费\n合计:合计\n到期日期:到期日期\n地址+栋号\n管理员:管理员\n已安装`
				},
				filterSearch: '', // 过虑搜索-只过滤当前数据
				multipleForm: {
					selectable: false, // 开启选框
					visible: false, // 选中的预览
				},
				allAccountInfo: [],
				selectedRows: [],
				Pay: {
					visible: false,
					formFields: [{}],
					submit_txt: '缴费'
				},
				account_id: '', // 账号id
				utils: {
					title: '', // 导航标题
					info: null, // 进入页面的个人信息
					date: '', // 查询时间
					keyword: '', // 模糊搜索
					is_type: 0, // 当前的身份类型 '0-新装、1-到期' 
					isQuick: false, // 设置类型 
				},
				dataList: [], // 表格数据
				images: [], // 图片数组
				recentYearsMonthDaysStart: [], // 默认的时间菜单选择
				columnsData: [], // 表头列表
				formFields: [], // 表单列表
				popup: {
					visible: false,
					submit_txt: '添加'
				},
			}
		},
		watch: {
			'utils.date'(val) {
				const [a, b] = val.split('至');
				if (a && b) {
					this.handleSearch();
				}
			}
		},
		computed: {
			GetFilterData() {
				return this.dataList.map(it => {
					if (this.filterSearch) {
						it.rowAll = [];
						if (it.displayedItemsCopy) {
							it.displayedItems = it.displayedItemsCopy
						}

						const displayedItems = it.displayedItems.filter(ch => this.filterSearch ? JSON.stringify(
								ch)
							.includes(this.filterSearch) : true);

						if (displayedItems.length) {
							if (!it.displayedItemsCopy) {
								it.displayedItemsCopy = it.displayedItems
							}

							it.displayedItems = displayedItems;
							return it
						}
						return false;
					};
					return it;
				}).filter(it => it);
			},
			getFixed() {
				return this.columnsData[this.columnsData.length - 1] || {
					fixed: ''
				}
			},
			quickFlag() {
				return !((!this.utils.isQuick && this.utils.is_type === 2) || this.utils.is_type === 0)
			},
			hasOperate() {
				const is = (this.has('/bill/details/pay') && this.quickFlag) || this.hasu('details') || this.hasr(
					'details');
				if (is) {
					if (this.getFixed?.key !== 'operate') {
						this.columnsData.push(...this.myColumns(['操作,operate,right']))
					}
				} else if (this.getFixed?.key === 'operate') {
					this.columnsData.splice(this.columnsData.length - 1, 1)
				}

				return is
			}
		}
	}
</script>

<style scoped>
	.container {
		padding: 10rpx;
		background-color: #fff;
		box-sizing: border-box;
	}

	.gap_img {
		border-radius: 4px;
	}

	.title {
		font-weight: bold;
		color: #000;
		border: solid 1px gainsboro;
		padding: 8px;
		box-sizing: border-box;
		border-bottom: none;
		border-top-left-radius: 4px;
		border-top-right-radius: 4px;
		box-shadow: 0 -1px 0 gainsboro;
		text-align: center;
		background: #db9b6d;
		font-size: 30px;
	}


	.w100 {
		width: 100%;
	}

	.w30 {
		width: 30%;
	}

	.zoom3 {
		zoom: .2
	}

	.convert-textarea {
		width: 100%;
		/* 宽度占满容器，也可以根据需要设置为固定值 */
		height: 200px;
		/* 高度，根据需要调整 */
		padding: 10px;
		/* 内边距 */
		box-sizing: border-box;
		/* 确保宽度包含内边距 */
		border: 2px solid #ccc;
		/* 边框颜色 */
		border-radius: 8px;
		/* 圆角 */
		background-color: #f8f8f8;
		/* 背景色 */
		color: #333;
		/* 文字颜色 */
		font-family: Arial, sans-serif;
		/* 字体 */
		font-size: 16px;
		/* 字号 */
		resize: vertical;
		/* 允许垂直调整大小 */
		transition: border-color 0.3s;
		/* 过渡动画 */
		box-sizing: border-box;
	}

	.convert-textarea:focus {
		border-color: #0066cc;
		/* 获得焦点时的边框颜色 */
		outline: none;
		/* 移除焦点时的默认轮廓线 */
	}

	.my-mask {
		position: fixed;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		display: flex;
		justify-content: center;
		align-items: center;
		z-index: 999;
	}

	.my-mask-overlay {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		background-color: rgba(0, 0, 0, 0.5);
	}

	.my-mask-content {
		display: flex;
		flex-direction: column;
		align-items: center;
	}

	.loading-icon {
		width: 50px;
		height: 50px;
		border: 4px solid #fff;
		border-top-color: transparent;
		border-radius: 50%;
		animation: spin 1s linear infinite;
	}

	@keyframes spin {
		to {
			transform: rotate(360deg);
		}
	}

	.loading-text {
		margin-top: 10px;
		font-size: 16px;
		color: #fff;
	}
</style>